# encoding: utf-8
# @File  : base.py
# @Author: wu shaofan
# @Date  :  2024/04/17
# @Desc :
import random
import time
import allure
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.select import Select
from selenium.webdriver.support.ui import WebDriverWait
import config


class Base:
    # 初始化
    def __init__(self, driver):
        self.driver = driver

    # 查找元素方法 (提供：点击、输入、获取文本)使用
    def base_find_element(self, loc, timeout=10, poll=0.5):
        # 等待元素出现，最多等待10秒，每0.5秒检查一次
        # return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(lambda x: x.find_element(*loc))
        # return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(expected_conditions.presence_of_element_located(loc), '元素未找到')
        try:
            ele = WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(expected_conditions.presence_of_element_located(loc), '元素未找到')
            return ele
        except Exception as e:
            time.sleep(0.5)
            print('第二次定位了')
            ele = WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(
                expected_conditions.presence_of_element_located(loc), '元素未找到')
            return ele

    # 查找一组元素方法 (提供：获取文本)使用
    def base_find_elements(self, loc, timeout=10, poll=0.5):
        # 等待元素出现，最多等待10秒，每0.5秒检查一次
        return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(expected_conditions.presence_of_all_elements_located(loc), '元素未找到')

    # 查找一组元素--带索引
    def base_find_elements_index(self, loc, index, timeout=10, poll=0.5):
        # 等待元素出现，最多等待10秒，每0.5秒检查一次
        return WebDriverWait(self.driver, timeout=timeout, poll_frequency=poll).until(expected_conditions.presence_of_all_elements_located(loc), '元素未找到')[index]

    # 点击方法
    def base_click(self, loc):
        try:
            WebDriverWait(self.driver, 10, 0.5).until(expected_conditions.element_to_be_clickable(loc)).click()
        except Exception as e:
            time.sleep(0.1)
            WebDriverWait(self.driver, 10, 0.5).until(expected_conditions.element_to_be_clickable(loc)).click()

    # 输入方法
    def base_input(self, loc, value):
        element = self.base_find_element(loc)
        # 清空
        element.clear()
        # 输入
        element.send_keys(value)

    # 输入方法，不需要清除
    def base_input_no_clear(self, loc, value):
        element = self.base_find_element(loc)
        # 输入
        element.send_keys(value)

    # 获取文本方法
    def base_get_text(self, loc):
        try:
            element = self.base_find_element(loc)
            return element.text
        except Exception as e:
            element = self.base_find_element(loc)
            return element.text



    # 获取一组元素文本方法
    def base_get_text_list(self, loc):
        element_list = self.base_find_elements(loc)

        text_list = []
        for element in element_list:
            text_list.append(element.text)

        return text_list

    # 获取一组元素文本方法
    def base_get_text_list_new(self, loc):
        # 根据给定的位置查找元素
        element_list = self.base_find_elements(loc)
        # 创建一个空列表来存储元素的文本
        text_list = []
        # 遍历元素列表，将每个元素的文本添加到列表中
        for element in element_list:
            # 调用元素的text方法获取元素的文本
            text_list.append(element.text)
        # 返回包含元素文本的列表
        return text_list

    # 刷新页面
    def base_refresh(self):
        self.driver.refresh()

    # 封装一个迭代器，生成从1到100的数字
    def base_get_numbers(self):
        for i in range(1, 101):
            yield i

    # 截图方法
    def base_get_image(self, name, num):
        path = config.BASE_DIR + r"/video/images/{}/{}.png".format(name, num)
        self.driver.get_screenshot_as_file(path)

    # allure报告截图方法
    def base_get_allure_image(self):
        allure.attach(self.driver.get_screenshot_as_png(), "截图", allure.attachment_type.PNG)

    # 移动滚动条方法
    def base_move_scroll_bar(self, y):
        js = "window.scrollTo(0, {})".format(y)
        self.driver.execute_script(js)

    # 鼠标双击方法
    def base_double_click(self, loc):
        ActionChains(self.driver).double_click(self.base_find_element(loc)).perform()

    # 鼠标悬停方法
    def base_move_to_element(self, loc):
        ActionChains(self.driver).move_to_element(self.base_find_element(loc)).perform()

    # 鼠标右击方法
    def base_right_click(self, loc):
        ActionChains(self.driver).context_click(self.base_find_element(loc)).perform()

    # 下拉框方法----根据选择option选项
    def base_select_by_option(self, loc, option):
        # self.base_if_element_exist(loc)
        ele = self.base_find_element(loc)
        # 实例化select对象
        select = Select(ele)
        # 通过select对象的index来选择广州
        select.select_by_index(option)

    # 下拉框方法---根据选择文本
    def base_select_by_text(self, loc, text):
        self.base_if_element_exist(loc)
        ele = self.base_find_element(loc)
        # 实例化select对象
        select = Select(ele)
        # 通过select对象的text来选择广州
        select.select_by_visible_text(text)

    # 检测iframe是否可用,可用就直接切入
    def base_if_frame_exist(self, loc):
        try:
            element = WebDriverWait(self.driver, 10, 0.5).until(
                expected_conditions.frame_to_be_available_and_switch_to_it(loc))
            return element
        except Exception as e:
            print("未找到iframe元素，错误信息：{}".format(e))
            return False

    # 查找元素判断是否操作成功
    def base_if_element_exist(self, loc):
        try:
            self.base_find_element(loc)
            # 找到元素，返回True
            return True
        except:
            # 未找到元素，返回False
            return False

    # 判断一组元素是否存在
    def base_if_elements_exist(self, loc):
        try:
            self.base_find_elements(loc)
            return True
        except:
            return False

    # 判断一组元素是否存在
    def base_if_elements_exist_index(self, loc, index):
        try:
            # 判断一组元素的第一个是否存在
            self.base_find_elements_index(loc, index)
            return True
        except:
            return False

    # 重新封装select
    def base_new_select(self, loc01, loc02, reason):
        """
        封装select
        :param loc01: 定位到select标签
        :param loc02: 定位到select下的option标签
        :return:
        """
        # # 判断是否有下拉框
        # if self.base_find_element(loc01):
        #     # 判断下拉框的option是否大于1个
        #     if len(self.base_find_elements(loc02)) > 1:
        #         # 获取option的个数
        #         city_len = len(self.base_find_elements(loc02))
        #         # 获取option的文本
        #         city_list = self.base_get_text_list_new(loc02)
        #         # 随机选择一个option,不包含“请选择”下拉框选项
        #         num = random.randint(1,city_len-1)
        #         # 定位到市下拉框的option，并选择
        #         self.base_select_by_option(loc01, num)
        #         # 截图
        #         self.base_get_allure_image()
        #         return city_list[num]
        #     else:
        #         return "下拉框中只有一个选项-请选择"
        # else:
        #     return reason

        # 判断是否有下拉框
        try:
            # 判断下拉框内可选项是否已经加载成功，不用此方法就要加上强制等待来确保成功率
            self.base_if_elements_exist(loc02)
            # 判断下拉框的option是否大于1个
            if len(self.base_find_elements(loc02)) > 0:
                # 获取option的个数
                city_len = len(self.base_find_elements(loc02))
                # 获取option的文本
                city_list = self.base_get_text_list(loc02)
                # 随机选择一个option,不包含“请选择”下拉框选项--random.randint(1, 2) 可以取到1或者2
                num = random.randint(1, city_len-1)
                # 定位到市下拉框的option，并选择
                self.base_select_by_option(loc01, num)
                # 截图
                self.base_get_allure_image()
                return city_list[num]
            else:
                return "请选择"
        except:
            return reason

    # 强制等待方法
    def base_time_sleep(self, time01):
        # 等待time秒
        time.sleep(time01)

    # 根据属性名获取元素属性值
    def base_get_element_attribute(self, loc, name):
        element = self.base_find_element(loc)
        return element.get_attribute(name)

    # 根据属性名获取元素属性值
    def base_get_elements_attribute(self, loc, i, name):
        element = self.base_find_elements_index(loc, i)
        return element.get_attribute(name)

    # 判断单选框或复选框是否选中
    def base_is_selected(self, loc):
        element = self.base_find_element(loc)
        return element.is_selected()

    # 获取toast的文本信息
    def base_get_toast_text(self, loc):
        # 获取toast的文本信息
        try:
            toast_text = WebDriverWait(self.driver, 10, 0.5).until(expected_conditions.presence_of_element_located(loc))
            return toast_text.text
        except Exception as e:
            pass


    # 后台登录封装
    def base_ht_login(self, username, password, code):
        # TODO 输入用户名
        login_username = By.NAME, 'username'
        self.base_input_no_clear(login_username,username)
        # TODO 输入密码
        login_pwd = By.NAME, 'password'
        self.base_input_no_clear(login_pwd,password)
        # TODO 输入验证码
        login_verify_code = By.NAME, 'vertify'
        self.base_input_no_clear(login_verify_code,code)
        # TODO 点击登录按钮
        login_btn = By.NAME, 'submit'
        self.base_click(login_btn)
